package cn.cjlmonster.hyouka_assistant.ai

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.Color
import android.os.Build
import android.util.Log
import android.view.View
import android.view.WindowInsetsController
import android.webkit.WebView
import androidx.appcompat.app.AppCompatActivity
import cn.cjlmonster.hyouka_assistant.WKPlugin
import cn.cjlmonster.hyouka_assistant.json.JTools
import com.google.gson.JsonObject
import com.gyf.immersionbar.ImmersionBar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch


fun AppCompatActivity.immersiveNavigationBar() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        window.statusBarColor = Color.TRANSPARENT
        window.setDecorFitsSystemWindows(false)
        window.isNavigationBarContrastEnforced = false
        window.insetsController?.run {
            // hide(WindowInsets.Type.displayCutout())
            setSystemBarsAppearance(
                WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS,
                WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS
            )
            setSystemBarsAppearance(
                WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS,
                WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS
            )
        }
    } else {
        window.statusBarColor = Color.TRANSPARENT
        window.navigationBarColor = Color.WHITE
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            window.decorView.systemUiVisibility =
                View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR or
                        View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
                        View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
                        View.SYSTEM_UI_FLAG_LAYOUT_STABLE
        }
    }
}

/**
 * 退出当前页面
 */
fun AppCompatActivity.goBack() {
    runOnUiThread { onBackPressedDispatcher.onBackPressed() }
}

/**
 * 切换屏幕方向
 */
fun AppCompatActivity.changeOrientation(isLandscape: Boolean) {
    runOnUiThread {
        requestedOrientation = when (isLandscape) {
            true -> ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
            false -> ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        }
    }
}

/**
 * js桥接的数据结构
 */
data class JavaScriptMessage(
    val id: Int,
    val method: String,
    val param: JsonObject,
    val callback: String
)

/**
 * 解析js数据
 */
fun CoroutineScope.solve(
    message: String,
    block: suspend (id: Int, method: String, param: JsonObject, callback: String) -> Unit
) {
    Log.i(WKPlugin.TAG, message)
    val m = JTools.toObj(message, JavaScriptMessage::class.java)
    launch(Dispatchers.Default) { block(m.id, m.method, m.param, m.callback) }
}

/**
 * js桥接，用于与js交互
 */
suspend fun WebView.evaluate(
    id: Int,
    callback: String,
    block: (suspend MutableMap<String, Any?>.() -> Unit)? = null
) {
    val param = block?.run {
        JTools.toJson(mutableMapOf<String, Any?>().apply { invoke(this) })
    } ?: "undefined"
    val function = "javascript:$callback($id, $param)"
    post { evaluateJavascript(function, null) }
}

fun WebView.evaluate(id: Int, callback: String, data: Map<*, *>) {
    val function = "javascript:$callback($id, ${JTools.toJson(data)})"
    post { evaluateJavascript(function, null) }
}

fun Context.startUI(clz: Class<*>, block: (Intent.() -> Unit)? = null) {
    Intent(this, clz).run {
        block?.invoke(this)
        startActivity(this)
    }
}

val Context.screenHeight: Int
    get() = resources.displayMetrics.heightPixels

val Context.statusBarHeight: Int
    get() = ImmersionBar.getStatusBarHeight(this)

val Context.statusBarHeightDp: Int
    get() = (statusBarHeight / resources.displayMetrics.density).toInt()

val Context.navigationBarHeight: Int
    get() = ImmersionBar.getNavigationBarHeight(this)

val Context.navigationBarHeightDp: Int
    get() = (navigationBarHeight / resources.displayMetrics.density).toInt()

val Activity.actionBarHeight: Int
    get() = ImmersionBar.getActionBarHeight(this)

val Activity.topMargin: Int
    get() = statusBarHeight + actionBarHeight